package com.unicloud.nifi.processor;

import com.unicloud.watcher.MailAcceptor;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.*;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;

import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.*;

public class MailWatcherProcessor extends AbstractProcessor {

    private List<PropertyDescriptor> properties;
    private Set<Relationship> relationships;
    private Store store;

    public static final PropertyDescriptor mail_user_name = new PropertyDescriptor.Builder()
            .name("emailUserName")
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();
    public static final PropertyDescriptor mail_password = new PropertyDescriptor.Builder()
            .name("emailPassword")
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();

    public static final Relationship SUCCESS = new Relationship.Builder()
            .name("SUCCESS")
            .description("Succes relationship")
            .build();


    @Override
    public void init(final ProcessorInitializationContext context )  {
        ArrayList<PropertyDescriptor> properties = new ArrayList<>();
        properties.add(mail_user_name);
        properties.add(mail_password);
//        防止多线程ADD
        this.properties = Collections.unmodifiableList(properties);
        Set<Relationship> relationships = new HashSet<>();
        relationships.add(SUCCESS);
//        防止多线程ADD
        this.relationships = Collections.unmodifiableSet(relationships);
        //
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imap");
        props.setProperty("mail.imap.host", "imap.163.com");
        props.setProperty("mail.imap.port", "143");

        // 创建Session实例对象
        Session session = Session.getInstance(props);
        try {
            Store store = session.getStore("imap");
            store.connect("gaojiax2014@163.com", "tomxin37");
            this.store = store;
        }catch (Exception ex){
            ex.printStackTrace();
        }

    }


    @Override
    public void onTrigger(ProcessContext processContext, ProcessSession processSession) throws ProcessException {
        final FlowFile flowFile = processSession.create();
        // To write the results back out ot flow file
         processSession.write(flowFile, (out) ->{
            AttachFileMailResult attachFileMailResult = fetchAttachFileFromEmail();
            if (attachFileMailResult == null || attachFileMailResult.inputStream == null) {
                return;
            }
            byte[] buffer = new byte[1024];
            int len = -1;
            while((len=attachFileMailResult.inputStream.read(buffer))!=-1){
                out.write(buffer,0,len);
            }
        });
        processSession.transfer(flowFile, SUCCESS);

    }

    AttachFileMailResult fetchAttachFileFromEmail() throws FileNotFoundException {
        try {
            Folder folder = store.getFolder("INBOX");
            folder.open(Folder.READ_WRITE);
            folder.getNewMessageCount();

            int messageCount = folder.getMessageCount();

            Message message[] = folder.getMessages(messageCount - folder.getNewMessageCount() + 1,messageCount);
//            Message message[] = folder.getMessages(messageCount,messageCount);
            if(message.length == 0){
                return null;
            }
            for (int i = 0; i < message.length; i++) {
                MimeMessage mimeMessage = (MimeMessage) message[i];
                Flags flags = mimeMessage.getFlags();
                boolean seen = flags.contains(Flags.Flag.SEEN);
                if(seen){
                    continue;
                }
                MailAcceptor re = new MailAcceptor(mimeMessage);
                re.getMailContent(mimeMessage);

                String bodyText = re.getBodyText();

                re.setAttachPath("d:\\");
                String fileName = re.saveAttachMent(mimeMessage);
//                  String fileName = "xx.md";
                if(fileName == null){
                    return null;
                }
                mimeMessage.setFlag(Flags.Flag.SEEN,true);
                File file = new File("d:\\"+fileName);
                FileInputStream fileInputStream = new FileInputStream(file);
                return  new AttachFileMailResult(fileInputStream,fileName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        FileInputStream fileInputStream = new FileInputStream("D:\\hello.txt");
        return  new AttachFileMailResult(fileInputStream,"noAttachFile.txt");
    }


    private static class AttachFileMailResult {
         InputStream inputStream;
         String fileName;

        public AttachFileMailResult(InputStream inputStream, String fileName) {
            this.inputStream = inputStream;
            this.fileName = fileName;
        }
    }


    @Override
    public Set<Relationship> getRelationships(){
        return relationships;
    }

    @Override
    public List<PropertyDescriptor> getSupportedPropertyDescriptors(){
        return properties;
    }

}
